home *** CD-ROM | disk | FTP | other *** search
/ Disc to the Future 2 / Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin / MAC / THINKC / 4_0 / IAC_STUF / IAC-DRIV.C next >
C/C++ Source or Header  |  1989-11-29  |  4KB  |  149 lines

  1.  
  2. /* Very simple driver to support IPC between applications.  Each application opens 
  3.    the driver (to be sure that its open) and then makes one control call to register
  4.    itself with a unique application number and a desired buffer size.
  5.    When an application wants to talk to another application, it makes a status
  6.    call with the number of the application and gets back the address of that
  7.    application's buffer.  It can then communicate by putting a message
  8.    directly into the buffer.  By convention, the first two bytes of the buffer
  9.    hold a count of the number of characters currently in the buffer, the next
  10.    two bytes hold the maximum size of the buffer and the format of the remainder
  11.    of the buffer should be agreed upon by the applications.  The supplied 'C'
  12.    routines support multiple messages in the buffer by making the first two bytes
  13.    of each message a message length word. */
  14.  
  15. #define NUM_APPS    2
  16. struct {
  17.     int appNumber;
  18.     int *buffer;
  19.     } appBuffers[NUM_APPS];
  20.  
  21. Boolean alreadyOpened = FALSE;
  22.  
  23. main(cntrlParam *paramBlock, DCtlPtr devCtlEnt, int n)
  24. {
  25.     int i;
  26.     THz zone;
  27.     Handle h;
  28.     
  29.     switch(n) {
  30.       case 0:        /* Open */
  31.           if (alreadyOpened)
  32.               return(noErr);
  33.               
  34.         if (devCtlEnt->dCtlStorage == 0)
  35.             return(openErr);
  36.  
  37.           alreadyOpened = TRUE;
  38.           
  39.           SysBeep(60);    /* Let's you know it's been loaded */
  40.           
  41.           /* Before doing anything else, lock the driver in place and detach its
  42.              resource. This is necessary so that the driver can survive after the
  43.              application that created it has exitted.  Unfortunately, this leaves it
  44.              in memory until the next reboot, but its not that large anyway.  */
  45.           HLock(devCtlEnt->dCtlDriver);
  46.           DetachResource(devCtlEnt->dCtlDriver);
  47.  
  48.           /* Initialize the application registration array */
  49.         for (i = 0; i < NUM_APPS; i++) {
  50.             appBuffers[i].appNumber = -1;
  51.             appBuffers[i].buffer = 0L;
  52.             }
  53.         return(noErr);
  54.  
  55.       case 1:        /* Prime */        
  56.         break;
  57.  
  58.       case 2:        /* Control */
  59.           switch(paramBlock->csCode) {
  60.             case 1:        /* Register an application */
  61.                 /* Make sure it doesn't already exist */
  62.               for (i = 0; i < NUM_APPS && appBuffers[i].appNumber != *(paramBlock->csParam); i++);
  63.               
  64.               /* Already exists, if requesting a different size buffer, return failure */
  65.               if (i != NUM_APPS) {
  66.                   if (*(appBuffers[i].buffer + 1) != *(paramBlock->csParam + 1))
  67.                       return(controlErr);
  68.                   else
  69.                       return(noErr);
  70.                   }
  71.  
  72.               /* Find a free slot */
  73.               for (i = 0; i < NUM_APPS && appBuffers[i].appNumber != -1; i++);
  74.               
  75.               /* If no more slots available, return failure */
  76.               if (i == NUM_APPS)
  77.                   return(controlErr);
  78.               
  79.               /* Record it in the table and allocate memory for it */
  80.               zone = GetZone();
  81.               SetZone(SystemZone());
  82.               if ((h = NewHandle(*(paramBlock->csParam + 1))) == 0L) {
  83.                   SetZone(zone);
  84.                   return(controlErr);
  85.                   }
  86.               MoveHHi(h);
  87.               HLock(h);
  88.               appBuffers[i].buffer = *(int **)h;
  89.               SetZone(zone);
  90.               
  91.               appBuffers[i].appNumber = *(paramBlock->csParam);              
  92.               *(appBuffers[i].buffer) = 0;
  93.               *(appBuffers[i].buffer + 1) = *(paramBlock->csParam + 1);
  94.               
  95.               return(noErr);
  96.               
  97.             case 2:        /* Unregister an application */
  98.               /* Find the application */
  99.               for (i = 0; i < NUM_APPS && appBuffers[i].appNumber != *(paramBlock->csParam); i++);
  100.               
  101.               /* Couldn't find it, return failure */
  102.               if (i == NUM_APPS)
  103.                   return(controlErr);
  104.               
  105.               zone = GetZone();
  106.               SetZone(SystemZone());
  107.               h = RecoverHandle(appBuffers[i].buffer);
  108.               DisposHandle(h);
  109.               SetZone(zone);
  110.               appBuffers[i].buffer = 0L;
  111.               appBuffers[i].appNumber = -1;
  112.               
  113.               return(noErr);
  114.             default:
  115.                 return(controlErr);
  116.               }
  117.  
  118.       case 3:        /* Status */
  119.               /* Find the application */
  120.               for (i = 0; i < NUM_APPS && appBuffers[i].appNumber != paramBlock->csCode; i++);
  121.               
  122.               /* Couldn't find it, return failure */
  123.               if (i == NUM_APPS) {
  124.                   *((void **)(paramBlock->csParam)) = 0L;
  125.                   return(statusErr);
  126.                   }
  127.               
  128.               *((int **)(paramBlock->csParam)) = appBuffers[i].buffer;
  129.               return(noErr);
  130.  
  131.       case 4:        /* Close */
  132.       
  133.           zone = GetZone();
  134.           SetZone(SystemZone());
  135.           
  136.           for (i = 0; i < NUM_APPS; i++)
  137.               if (appBuffers[i].appNumber != -1) {
  138.                   h = RecoverHandle(appBuffers[i].buffer);
  139.                   DisposHandle(h);
  140.                   }
  141.           SetZone(zone);
  142.  
  143.         return(noErr);
  144.  
  145.     default:
  146.         break;
  147.         }
  148.     return(openErr);
  149. }